package java_thinking.unit_21._21_3;

import javax.servlet.GenericServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.math.BigInteger;

/**
 * @Desc:   3-13 使用指向不可变容器对象的 volatile 类型引用以缓存最新结果
 * @author: cww
 * @DateTime: 2019-06-01 16:02
 */

public class VolatileCachedFactorize extends GenericServlet implements Servlet {
    /**
     * 使用 OneValueCache 来保存缓存的数值以及其因数，当一个线程将 volatile 类型的cache设置为一个新的
     * OneValueCache 引用时，其他线程就会立即看到缓存的数据；而OneValueCache 是不可变的对象，这样实现
     * 了线程安全的缓存相关变量，并且没有显示的使用锁的情况下实现的。
     */
    private volatile OneValueCache cache = new OneValueCache(null,null);
    @Override
    public void service(ServletRequest req, ServletResponse resp) {
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = cache.getFactor(i);
        if (factors == null) {
            factors = factor(i);
            cache = new OneValueCache(i,factors);
        }
    }
    void encodeIntoResponse(ServletResponse resp, BigInteger[] factors) {
    }

    BigInteger extractFromRequest(ServletRequest req) {
        return new BigInteger("7");
    }

    BigInteger[] factor(BigInteger i) {
        // Doesn't really factor
        return new BigInteger[]{i};
    }
}
